package smlab.astar
{
	import flash.events.Event;
	import flash.geom.Point;
	import flash.utils.ByteArray;
	
	import smlab.utils.DisplayObjectUtil;
	import smlab.utils.GeomUtil;

	/**
	 * 人物行走
	 * @author tb
	 *
	 */
	public class WalkAction implements IWalk
	{
		private var _isPlaying:Boolean = false;
		protected var _actor:Actor;
		private var _path:Array;
		private var _length:int;
		private var _currentCount:uint = 0;
		private var _nextNum:uint;
		private var _disPos:Point;
		private var _curPos:Point;
		private var _nextP:Point;
		private var _endP:Point;
		private var _speed:Number;

		//运行深度计数用的
		private var _count:int;

		public function WalkAction()
		{

		}

		public function init():void
		{
			_isPlaying = false;
			_path = null;
			_length = 0;
			_currentCount = 0;
			_curPos = null;
			_nextP = null;
			_endP = null;
			_nextNum = 0;
			_count = 0;
		}

		public function get isPlaying():Boolean
		{
			return _isPlaying;
		}

		public function execute(obj:Actor, data:Object, isNet:Boolean = true):void
		{
			if (data is Point)
			{
				executePoint(obj, data as Point, isNet);
			}
			else if (data is Array)
			{
				executArray(obj, data as Array);
			}
		}

		/**
		 * 开始执行行走
		 * @param people 行走显示对象
		 * @param endPos 到达的点
		 * @param isNet  是否发送到网络广播
		 *
		 */
		public function executePoint(obj:Actor, endPos:Point, isNet:Boolean = true):void
		{
			var paths:Array = AStar.find(obj.pos, endPos);

			if (paths)
			{
				init();

				_actor = obj;
				_path = paths;
				_length = _path.length;
				_endP = endPos;

				if (_length > 1)
				{
					_path[0] = _actor.pos;
					play();
					if (isNet)
					{
						var by:ByteArray = new ByteArray();
						by.writeObject(_path);
					}
				}
			}
		}

		public function executArray(obj:Actor, pdata:Array):void
		{
			init();
			_actor = obj;
			_path = [];

			_length = pdata.length;
			for (var i:int = 0; i < _length; i++)
			{
				var p:Object = pdata[i];
				_path.push(new Point(p.x, p.y));
			}
			_endP = _path[_length - 1];
			play();
		}

		public function play():void
		{
			_isPlaying = true;
			nextFun();
			_actor.addEventListener(Event.ENTER_FRAME, loop);
		}

		public function stop():void
		{
			_isPlaying = false;
			if (_actor)
			{
				_actor.removeEventListener(Event.ENTER_FRAME, loop);
			}

		}

		public function destroy():void
		{
			stop();
			_actor = null;
			init();
		}

		public function get remData():Array
		{
			return _path.slice(_currentCount);
		}

		public function get endPoint():Point
		{
			return _endP;
		}

		private function loop(e:Event):void
		{
			if (!_isPlaying)
			{
				return;
			}
			_actor.pos = _curPos;
			if (Point.distance(_curPos, _nextP) <= _speed / 2)
			{
				if (_nextNum >= _length - 1)
				{
					if (_actor.parent)
					{
						DepthManager.swapDepth(_actor, _actor.y);
					}
					stop();
					return;
				}
				else
				{
					nextFun();
				}
			}
			_curPos = _curPos.add(_disPos);

			setDepth();
		}

		/**
		 * 设置层深
		 *
		 */
		private function setDepth():void
		{
			if (_count % 4 == 0)
			{
				if (_actor)
				{
					if (_actor.parent)
					{
						DepthManager.swapDepth(_actor, _actor.y);
					}
				}
			}
			_count++;
		}

		/**
		 * 行走下一点
		 *
		 */
		private function nextFun():void
		{
			_speed = _actor.speed;
			_curPos = _path[_currentCount];
			_nextNum = _currentCount + 1;
			_nextP = _path[_nextNum];
			_actor.rotation=GeomUtil.pointAngle(_curPos,_nextP);
			_disPos = GeomUtil.angleSpeed(_nextP, _curPos);
			_disPos.x *= _speed;
			_disPos.y *= _speed;

			_currentCount++;
		}
	}
}
